#ifndef VARIABLE_H
#define VARIABLE_H

#include <QObject>
#include <QtDebug>

#include "fraction.h"

#pragma region Value - reprezentacja zmiennej

enum VariableType
{
	FractionType,
	BooleanType,
	VoidType,
	DoesntMatterType,
	HaveNoIdeaType
};

class Value
{
private:
	VariableType m_Type;
	QString		 m_Value;

public:

	Value() {}
	Value(VariableType v, QString s) : m_Type(v), m_Value(s) {}
	~Value(){}

	bool isFraction() { return m_Type == FractionType; }
	bool isBoolean() { return m_Type == BooleanType; }
	bool isVoid() { return m_Type == VoidType; }

	bool toBoolean()
	{
		if(m_Type == BooleanType)
		{
			return m_Value == QObject::tr("true");
		}
		else
		{
			qDebug() << "ERR: toBoolean()";
			return false;
		}
	}

	Fraction toFraction()
	{
		//// liczba i licznik | mianownik
		//if(m_Value.contains('i'))
		//{
		//	QStringList tmp = m_Value.split('i');
		//	int liczba = tmp[0].toInt();
		//	tmp = tmp[1].split('|');
		//	int licznik = tmp[0].toInt();
		//	int mianownik = tmp[1].toInt();

		//	return Fraction(liczba, licznik, mianownik);
		//}
		//// licznik | mianownik
		//if(m_Value.contains('|'))
		//{
		//	QStringList tmp = m_Value.split('|');
		//	int licznik = tmp[0].toInt();
		//	int mianownik = tmp[1].toInt();

		//	return Fraction(0, licznik, mianownik);
		//}
		//// liczba
		//return Fraction(m_Value.toInt(), 0, 0);
		return Fraction(m_Value);
	}

	QString toString()
	{
		return m_Value;
	}


	void setValue(QString val)
	{
		m_Value = val;
	}

	VariableType type() { return m_Type; }	
};

#pragma endregion

class Variable
{
private:
	Value	m_Val;
	QString m_Id;

public:
	Variable(){}
	Variable(Value val, QString id) : m_Val(val), m_Id(id){}
	Variable(VariableType type, QString id, QString val ) : m_Val(type ,val), m_Id(id){}
	~Variable(){}

	Value value() { return m_Val; }
	QString id() {return m_Id; }

	void setValue(QString v) { m_Val.setValue(v); }

	bool operator==(const Variable &v) { return m_Id == v.m_Id; }
};






#pragma region Scope - reprezentacja zmiennych lokalnych

class Scope
{
public:
	Scope();
	Scope(Scope* parent);
	~Scope();	

private:

	Scope* parent;					// widok nadrzedny, do obslugi rekurencji

	QList<Variable> args;			// lista argumentow
	Value ret;						// zwracana wartosc
	QList<Variable> variables;		// przerozne zadeklarowane zmienne


};

#pragma endregion

#endif // VARIABLE_H